module EXEC     (
        //      Inputs
        id_ex,
        addr_in,
        rf1,
        rf2,
        inst,
        clk,
        rst,
        //      Outputs
        ex_mem,
        addr_out, 
        alu_out_pl,
        rf1_pl,
        ext_pl,
        inst_pl,
        err     );

        input   [19:0]  id_ex; 
        input   [15:0]  addr_in;
        input   [15:0]  rf1;
        input   [15:0]  rf2;
        input   [10:0]  inst;
        input           clk;
        input           rst;

        output  [11:0]  ex_mem;
        output  [15:0]  addr_out;
        output  [15:0]  alu_out_pl;
        output  [15:0]  rf1_pl;
        output  [15:0]  ext_pl;
        output  [8:0]   inst_pl;
        output          err;
       /*       CTRL SIGNALS IN EXEC STAGE      */ 
        wire    [7:0]   ex;
        wire    [2:0]   ext;
        wire            alusrc2;
        wire    [3:0]   aluop;
        assign          ex = id_ex[19:12];
        assign          ext = ex[7:5];
        assign          alusrc2 = ex[4];
        assign          aluop = ex[3:0];
       /*       CTRL SIGNALS IN FOLLOWING STAGES        */ 
        dff     ex_mem[11:0]       
        (
                .q ( ex_mem ),
                .d ( id_ex[11:0] ),
                .clk ( clk ),
                .rst ( rst )
        );
        /*      PIPELINE : DATA PATH    */
        dff     addr[15:0]
        (
                .q ( addr_out ),
                .d ( addr_in ),
                .clk ( clk ),
                .rst ( rst )
        );
        dff     alu_out[15:0]   
        (
                .q ( alu_out_pl ),
                .d ( alu_out ),
                .clk ( clk ),
                .rst ( rst )
        );
        dff     rf1[15:0]       
        (
                .q ( rf1_pl ),
                .d ( rf1 ),
                .clk ( clk ),
                .rst ( rst )
        );
        wire    [15:0]  immd16;
        dff     ext_out[15:0]
        (
                .q ( ext_pl ),
                .q ( immd16 ),
                .clk ( clk ),
                .rst ( rst )
        );
        dff     inst[8:0]
        (
                .q ( inst_pl ),
                .d ( inst[10:2] ),
                .clk ( clk ),
                .rst ( rst )
        );
        /*      PIPELINE : EXEC STAGE   */
        ext     ext     (
                .immd ( inst ),
                .mode ( ext ),
                .immd16 ( immd16 )      
        );
        wire    [3:0]   aluctr;
        aluctr  aluctr  (
                .aluop ( aluop ),
                .funct ( inst[1:0] ),
                .aluctr ( aluctr )
        );
        wire    [15:0]  alu_op2;
        assign  alu_op2 = aluscr2 ? immd16 : rf2;
        alu     alu     (
                .op1 ( rf1 ),
                .op2 ( alu_op2 ),
                .aluctr ( aluctr ),
                .out ( alu_out ),
                .carry_out ( )
        );

endmodule
